/*
 * @Author: zhangfeng
 * @Date: 2023-12-18 16:24:47
 * @LastEditTime: 2024-01-12 10:33:59
 * @LastEditors: zhangfeng
 * @Description:
 * @FilePath: \manager\managersystem\src\utils\utils.ts
 * © 2023 张峰，All rights reserved.
 */

/**
 * 封装树结构数据
 * @param data 要封装的数据
 * @param parentId 父级元素parentId默认值为0
 * @returns MenuItemTree[]
 */
import router from '../router';

export const buildTree = (
	data: MenuItem[],
	parentId = 0
): MenuItemTree[] | null => {
	const children = data.filter((item) => item.parentId === parentId);
	if (children.length === 0) {
		return null;
	}
	return children.map((child) => {
		return {
			...child,
			children: buildTree(data, child.id),
		};
	});
};
/**
 * 封装带disabled的树形结构
 * @param data 树形结构数据数组
 * @param target 要disabled数据
 * @returns MenusItemDisabled[]
 */
export const buildTreeDisabled = (
	data: Ref<MenusItemDisabled[]>,
	target: MenuItem | null
) => {
	const rawData: MenusItemDisabled[] = data.value;
	return recursionDisabled(rawData, target);
};

/**
 * 修改目标元素的父级的一些禁止选项
 * 1 目标元素本身不能作为自己的父级元素
 * 2 不能修改目标元素的父级作为修改后的目标元素的父级（已经是他的父级元素了）
 * 3 在一下修改中目标元素的子元素不能作为修改后目标元素的父级
 * 递归查找要disable的数据
 * 目标元素 目标元素的父元素及目标元素的所有子元素都为disabled,
 * @param rawData  树形结构
 * @param target  目标元素
 * @returns MenusItemDisabled[]
 */
const recursionDisabled = (
	rawData: MenusItemDisabled[],
	target: MenuItem | null
): MenusItemDisabled[] => {
	return rawData.map((v) => {
		if (target?.parentId === v.id) {
			v.disabled = true;
			if (v.children) {
				v.children.map((el) => {
					if (el.id === target.id) {
						el.disabled = true;
						if (el.children) {
							findAllChildrenSetDisable(el.children, target);
						}
					} else {
						el.disabled = false;
						if (el.children) {
							findAllChildrenSetDisable(el.children, target, false);
						}
					}
					return el;
				});
			}
			return v;
		} else {
			if (v.children) {
				recursionDisabled(v.children, target);
			}
			v.disabled = false;
			return v;
		}
	});
};

const findAllChildrenSetDisable = (
	v: MenusItemDisabled[],
	target: MenuItem,
	type: boolean = true
): MenusItemDisabled[] => {
	return v.map((el) => {
		if (el.children) {
			findAllChildrenSetDisable(el.children, target);
		}
		el.disabled = type;
		return el;
	});
};

const modules = import.meta.glob('@/views/**/*.vue');
const loadComponent = async (path: string) => {
	if (modules[path]) {
		const module = await (modules[path]() as Promise<{ default: any }>);
		return module.default;
	} else {
		const module = await (modules['/src/views/ErrorPage.vue']() as Promise<{
			default: any;
		}>);
		return module.default;
	}
};
export const generateMenus = (data: MenuItem[]) => {
	const result = data.filter((menu) => menu.level != 3);
	const res = buildTree(result) as MenuItemTree[];
	return res;
};
// export const generateRoutes = async (route: MenuItem[]) => {
// 	console.log(route);
// 	let routes = route.filter((v) => v.level != 3);
// 	const res = [];
// 	const baseRouter: premissionRouter[] = [
// 		{
// 			path: '/',
// 			name: '',
// 			component: await loadComponent('/src/views/layout/AppLayout.vue'),
// 			meta: {
// 				requiresAuth: true,
// 			},
// 		},
// 	];
// 	router.addRoute({
// 		path: '/',
// 		name: 'base',
// 		component: await loadComponent('/src/views/layout/AppLayout.vue'),
// 		meta: {
// 			requiresAuth: true,
// 		},
// 	});
// 	for (const route of routes) {
// 		const meta = {
// 			title: route.name,
// 			icon: route.icon,
// 			hidden: !route.shown,
// 			requiresAuth: false,
// 		};
// 		let data = {
// 			path: '/' + route.path,
// 			name: route.path,
// 			component: await loadComponent(`/src/views${route.components}.vue`),
// 			meta: meta,
// 		};
// 		router.addRoute('base', data);
// 		res.push(data);
// 	}

// 	router.addRoute({
// 		path: '/:xxx(.*)*',
// 		name: 'ErrorPage',
// 		meta: {
// 			requiresAuth: false,
// 		},
// 		component: await loadComponent('/src/views/ErrorPage.vue'),
// 	});
// 	baseRouter[0].children = res;
// 	return baseRouter;
// };

export const generateRoutes = async (routes: MenuItemTree[]) => {
	router.addRoute({
		path: '/',
		name: 'base',
		component: await loadComponent('/src/views/layout/AppLayout.vue'),
		meta: {
			requiresAuth: true,
		},
	});
	for (const route of routes) {
		// 目录
		if (route.level == 1) {
			const parentView = route.path || 'parentView';
			router.addRoute('base', {
				path: '/' + parentView,
				name: parentView,
				component: await loadComponent(
					`/src/views/layout/components/ParentView.vue`
				),
				meta: {
					title: route.name,
					icon: route.icon,
					hidden: !route.shown,
					requiresAuth: false,
				},
			});
			if (route.children && parentView) {
				await generationChildRouter(route.children, parentView);
			}
		}
		// 菜单
		else {
			router.addRoute('base', {
				path: '/' + route.path,
				name: route.path,
				component: await loadComponent(`/src/views${route.components}.vue`),
				meta: {
					title: route.name,
					icon: route.icon,
					hidden: !route.shown,
					requiresAuth: false,
				},
			});
		}
	}
	router.addRoute({
		path: '/:xxx(.*)*',
		name: 'ErrorPage',
		meta: {
			requiresAuth: false,
		},
		component: await loadComponent('/src/views/ErrorPage.vue'),
	});
	return {};
};

const generationChildRouter = async (
	routes: MenuItemTree[],
	parentName: string
) => {
	for (const route of routes) {
		router.addRoute(parentName, {
			path: '/' + route.path,
			name: route.path,
			component: await loadComponent(`/src/views${route.components}.vue`),
			meta: {
				title: route.name,
				icon: route.icon,
				hidden: !route.shown,
				requiresAuth: false,
			},
		});
	}
};

export const generatePremission = async (data: MenuItem[]) => {
	let result: string[] = [];
	const premissionBtn = data.filter((menus) => menus.level == 3);
	premissionBtn.map((v) => {
		result.push(v.premi as string);
	});
	return result;
};

export const generateMenusShown = (menus: MenuItemTree[]): MenuItemTree[] => {
	const result = menus.filter((menu) => {
		if (menu.shown) {
			if (menu.children) {
				menu.children = generateMenusShown(menu.children);
				return menu;
			} else {
				return menu;
			}
		}
	});
	return result;
};
